package com.java.reflection;

import com.java.reflection.test.Child;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ConstructorAPI {
    // Class中与Constructor相关的API：newInstance、getConstructors、getConstructor、getDeclaredConstructors、getDeclaredConstructor
    public static void classAboutConstructor() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> childCls = Class.forName("com.java.reflection.test.Child");
        
        // 通过Class实例的无参构造newInstance实例化对象
        Child childIns = (Child) childCls.newInstance();
    }
    
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> childCls = Class.forName("com.java.reflection.test.Child");
        Constructor<?> childPublicConstructor = childCls.getConstructor(String.class, String.class);
        
        // newInstance：实例化Constructor实例表示的类
        childCls.getConstructor().newInstance();
        childCls.getConstructor(String.class, String.class).newInstance("OuterChildPrivateVar", "OuterChildPublicVar");
        
        // setAccessible：参数为true表示抑制访问检查，暴力访问私有构造函数
        Constructor<?> childPrivateConstructor = childCls.getDeclaredConstructor(String.class);
        childPrivateConstructor.setAccessible(true);
        childPrivateConstructor.newInstance("OuterChildPrivateVar");
        
        // getDeclaringClass：获取构造函数所表示的类的Class实例
        System.out.println(childPublicConstructor.getDeclaringClass()); // class com.java.reflection.test.Child
        
        // getName：获取构造函数所表示类的全限定类名
        System.out.println(childPublicConstructor.getName()); // com.java.reflection.test.Child
        
        // getParameterCount：获取构造函数形参个数
        System.out.println(childPublicConstructor.getParameterCount()); // 2
        
        // getParameterTypes：Class形式获取构造函数的所有形参类型
        ReflectionUtil.println(childPublicConstructor.getParameterTypes()); // String String
        
        // getGenericParameterTypes：Type形式获取构造函数的所有形参类型
        ReflectionUtil.println(childPublicConstructor.getGenericParameterTypes()); // java.lang.String java.lang.String
        
        // toGenericString：获取构造函数的详细信息
        System.out.println(childPublicConstructor.toGenericString()); // public com.java.reflection.test.Child(java.lang.String,java.lang.String)
    }
}
